package com.caikun.gateway.filter;

import com.caikun.model.common.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import org.springframework.web.client.RestTemplate;

/**
 * 权限验证过滤器 - 用于验证用户权限
 */
@Slf4j
@Component
public class PermissionGatewayFilterFactory extends AbstractGatewayFilterFactory<PermissionGatewayFilterFactory.Config> {

    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    public PermissionGatewayFilterFactory() {
        super(Config.class);
        this.restTemplate = new RestTemplate();
        this.objectMapper = new ObjectMapper();
    }

    /**
     * 过滤器逻辑
     */
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();

            // 获取需要的用户类型
            Integer requiredUserType = getRequiredUserType(path);
            if (requiredUserType == null) {
                // 不需要权限验证
                return chain.filter(exchange);
            }

            // 从请求头获取用户ID
            String userId = request.getHeaders().getFirst("X-User-Id");
            if (userId == null) {
                return onAuthFailure(exchange, "用户ID不存在", HttpStatus.UNAUTHORIZED);
            }

            log.info("用户ID: {}， 访问权限校验：{}", userId, requiredUserType);

            // 验证用户权限
            if (!validatePermission(userId, requiredUserType)) {
                return onAuthFailure(exchange, "权限不足", HttpStatus.FORBIDDEN);
            }

            return chain.filter(exchange);
        };
    }

    /**
     * 根据路径判断需要的用户类型
     */
    private Integer getRequiredUserType(String path) {
        if (path.startsWith("/api/admin/")) {
            return 2; // 管理员权限
        } else if (path.startsWith("/api/doctor/")) {
            return 1; // 医生权限
        } else if (path.startsWith("/api/patient/")) {
            return 0; // 患者权限
        }
        return null; // 不需要权限验证
    }

    /**
     * 验证用户权限
     */
    private boolean validatePermission(String userId, Integer requiredUserType) {
        try {
            // 调用用户服务验证权限
            String url = "http://user-service/user/permission/" + userId + "/" + requiredUserType;
            String response = restTemplate.getForObject(url, String.class);
            
            if (response != null) {
                Result<Boolean> result = objectMapper.readValue(response, 
                    objectMapper.getTypeFactory().constructParametricType(Result.class, Boolean.class));
                return result != null && result.getCode() == 200 && Boolean.TRUE.equals(result.getData());
            }
        } catch (Exception e) {
            System.err.println("权限验证失败: " + e.getMessage());
        }
        return false;
    }

    /**
     * 认证失败时的响应处理
     */
    private Mono<Void> onAuthFailure(ServerWebExchange exchange, String error, HttpStatus status) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(status);
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, "application/json");

        String body = String.format("{\"code\": %d, \"message\": \"%s\"}",
                status.value(), error);

        return response.writeWith(Mono.just(response.bufferFactory().wrap(body.getBytes())));
    }

    /**
     * 过滤器配置类
     */
    public static class Config {
        public Config() {
        }
    }
} 